<template>
    <div v-loading="loading" class="fg-cropper">
        <div class="crp-box">
            <div class="crp-nav">
                <el-button
                    v-for="(item, index) in btnGroup"
                    :key="index"
                    :ref="item.ref"
                    :disabled="loading"
                    :icon="item.icon"
                    :title="item.tit"
                    type="text"
                    @click="handleClick(`${item.type}`)"
                >
                    <template v-if="!item.icon" slot>
                        {{item.icon ? '' : item.name}}
                    </template>
                </el-button>
            </div>
            <div class="crp-main">
                <vue-cropper
                    v-if="originImg"
                    ref="cropper"
                    :container-style="containerStyle"
                    :aspect-ratio="ratio"
                    :src="originImg"
                ></vue-cropper>
            </div>
        </div>
    </div>
</template>

<script lang="ts">
import {
    Vue,
    Prop,
    Component
} from 'nuxt-property-decorator'
import 'cropperjs/dist/cropper.css'
const vueCropper = require('vue-cropperjs').default
@Component({
    name: 'fgCropper',
    components: {
        vueCropper
    }
})
export default class FgCropper extends Vue {
    @Prop({
        default: 800,
        type: Number
    })
    maxWidth!: number
    @Prop({
        default: 400,
        type: Number
    })
    minWidth!: number
    @Prop({
        default: 0,
        type: Number
    })
    ratio!: number
    @Prop()
    originImgFile!: any
    originImg: string = './img/sprites.png'
    // newImg: string = ''
    containerStyle: any = {
        width: this.maxWidth + 'px',
        maxWidth: '800px',
        minWidth: this.minWidth + 'px',
        height: (this.ratio ? this.maxWidth / this.ratio : this.maxWidth) + 'px',
        maxHeight: '600px',
        minHeight: '300px'
    }
    newImgFiles: any = {}
    loading: boolean = false
    btnGroup: [any, any, any, any] = [
        {
            tit: '放大',
            icon: 'el-icon-zoom-in',
            name: 'ZI',
            type: 'ZI'
        },
        {
            tit: '缩小',
            icon: 'el-icon-zoom-out',
            name: 'ZO',
            type: 'ZO'
        },
        // {
        //     tit: '顺时针旋转',
        //     icon: 'el-icon-refresh-right',
        //     name: 'RR',
        //     type: 'RR'
        // },
        // {
        //     tit: '逆时针旋转',
        //     icon: 'el-icon-refresh-left',
        //     name: 'RL',
        //     type: 'RL'
        // },
        // {
        //     tit: '水平方向翻转',
        //     name: 'X',
        //     type: 'FX',
        //     ref: 'flipX'
        // },
        // {
        //     tit: '垂直方向翻转',
        //     name: 'Y',
        //     type: 'FY',
        //     ref: 'flipY'
        // },
        {
            tit: '关闭',
            icon: 'el-icon-close',
            name: 'C',
            type: 'C'
        },
        {
            tit: '确认',
            icon: 'el-icon-check',
            name: 'S',
            type: 'S'
        }
    ]
    toBlobFix () {
        if (!HTMLCanvasElement.prototype.toBlob) {
            Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', {
                value (callback: any, type: any, quality: any) {
                    const canvas = this
                    setTimeout(() => {
                        const binStr = atob(canvas.toDataURL(type, quality).split(',')[1])
                        const len = binStr.length
                        const arr = new Uint8Array(len)
                        for (let i = 0; i < len; i++) {
                            arr[i] = binStr.charCodeAt(i)
                        }
                        callback(new Blob([arr], {type: type || 'image/png'}))
                    })
                }
            })
        }
    }
    getNewImg () {
        this.loading = true;
        (this.$refs.cropper as any).getCroppedCanvas().toBlob((blob: any) => {
            const file = this.originImgFile.file
            blob.name = file.name
            blob.uid = file.uid
            blob.lastModified = file.lastModified
            this.newImgFiles.file = blob
            this.loading = false
            this.$emit('getNewImgCallback', this.newImgFiles)
        })
    }
    zoomArea (n: any) {
        (this.$refs.cropper as any).relativeZoom(n)
    }
    changeRotate (deg: any) {
        (this.$refs.cropper as any).rotate(deg)
    }
    // x、y 镜像翻转
    flipMirror (type?: any) {
        const sign = type ? 'Y' : 'X'
        const dom = (this.$refs[`flip${sign}`] as any).$el
        let scale = dom.getAttribute('data-scale')
        scale = scale ? -scale : -1;
        (this.$refs.cropper as any)[`scale${sign}`](scale)
        dom.setAttribute('data-scale', scale)
    }
    handleClick (type: any) {
        switch (type) {
            case 'ZI':
                this.zoomArea(0.2)
                break
            case 'ZO':
                this.zoomArea(-0.2)
                break
            case 'RR':
                this.changeRotate(90)
                break
            case 'RL':
                this.changeRotate(-90)
                break
            case 'FX':
                this.flipMirror()
                break
            case 'FY':
                this.flipMirror('Y')
                break
            case 'C':
                this.$emit('closeCallback')
                break
            case 'S':
                this.getNewImg()
                break
        }
    }
    created () {
        const files = {...this.originImgFile}
        const file = files.file
        this.newImgFiles = {...files}
        delete this.newImgFiles.file
        this.originImg = window.URL.createObjectURL(file)
        this.toBlobFix()
    }
}
</script>

<style lang="scss" scoped>
    .fg-cropper{
        .crp-box{
            position: relative;
        }
        .crp-nav{
            position: absolute;
            top: 100%;
            width: auto;
            text-align: center;
            left: 50%;
            transform: translateX(-50%);
            background-color: #fff;
            margin-top: 4px;
            padding: 2px 9px;
            border-radius: 2px;
            line-height: normal;
            .el-button{
                height: 26px;
                width: 26px;
                margin: 0 9px;
                font-size: 16px;
                text-align: center;
                line-height: 26px;
                padding: 0;
                color: #666;
                border: 1px solid transparent;
                &:hover{
                    border-color: #666;
                }
                i{
                    font-size: 20px;
                    line-height: 26px;
                }
            }
        }
    }
</style>
